package enums

import "github.com/xuri/excelize/v2"

type ConstraintDto struct {
	HeaderNames []string
	HeaderKeys  []string
	DropDowns   []string
	FirstCol    int
	LastCol     int
	FirstRow    int
	LastRow     int
	CommentStr  string
	Validation  *excelize.DataValidation
	Protocol    string
}

var (
	// 产品变量模板固定列(数组长度需一致)
	DataHeaderName = []string{"设备", "变量名称", "变量标识", "单位"}
	DataHeaderKey  = []string{"sn", "label", "key", "param.unit"}
)

var (
	modbusConstraintDto = ConstraintDto{
		Protocol:    "MODBUS",
		HeaderNames: []string{"变量类型", "寄存器地址", "基础值", "倍率", "读取个数", "读功能码", "写功能码", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.read", "param.param.write", "param.param.offset"},
	}
	siemensS7MPIConstraintDto = ConstraintDto{
		Protocol:    "西门子S7",
		HeaderNames: []string{"变量类型", "寄存器地址", "基础值", "倍率", "内部偏移", "寄存器存储区", "读取个数"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.calc.base", "param.calc.mult", "param.param.offset", "param.param.area", "param.param.count"},
	}
	melsecConstraintDto = ConstraintDto{
		Protocol:    "三菱Melsec",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
	omronConstraintDto = ConstraintDto{
		Protocol:    "欧姆龙Omron",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
	opcUAConstraintDto = ConstraintDto{
		Protocol:    "OPC UA",
		HeaderNames: []string{},
		HeaderKeys:  []string{},
	}
	opcDAConstraintDto = ConstraintDto{
		Protocol:    "OPC DA",
		HeaderNames: []string{},
		HeaderKeys:  []string{},
	}
	bacnetConstraintDto = ConstraintDto{
		Protocol:    "BACnet",
		HeaderNames: []string{},
		HeaderKeys:  []string{},
	}
	geConstraintDto = ConstraintDto{
		Protocol:    "GE SRTP",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
	abConstraintDto = ConstraintDto{
		Protocol:    "罗克韦尔Allen Bradley",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
	beckhoffConstraintDto = ConstraintDto{
		Protocol:    "倍福Beckhoff",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
	yaskawaConstraintDto = ConstraintDto{
		Protocol:    "安川Memobus",
		HeaderNames: []string{"变量类型", "寄存器地址", "寄存器存储区", "基础值", "倍率", "读取个数", "内部偏移"},
		HeaderKeys:  []string{"param.type", "param.param.reg", "param.param.area", "param.calc.base", "param.calc.mult", "param.param.count", "param.param.offset"},
	}
)

var ProtocolParamConstraint = map[string]ConstraintDto{
	// MODBUS
	"modbus": modbusConstraintDto,
	// 西门子
	"siemens": siemensS7MPIConstraintDto,
	// 三菱
	"mc": melsecConstraintDto,
	// 欧姆龙
	"omron": omronConstraintDto,
	// opc
	"opcua": opcUAConstraintDto,
	"opcda": opcDAConstraintDto,
	// bacnet
	"bacnet": bacnetConstraintDto,
	// ge
	"ge": geConstraintDto,
	// ab
	"ab": abConstraintDto,
	// beckhoff
	"beckhoff": beckhoffConstraintDto,
	// yaskawa
	"yaskawa": yaskawaConstraintDto,
}

var (
	GateTypeMap = map[string]string{
		"X1":    "a1s2d3",
		"DTU":   "b1n2m3",
		"路由器":   "q1w2e3",
		"H6210": "x1y2z3",
		//"H6210(SHDDM)": "ScHalfDfsDeviceM",
		//"H6210(SAOPM)": "ScAutoOtherPlatM",
		//"H6210(SDfDM)": "ScDfsDeviceM",
		//"H6210(SDpDM)": "ScDpuDeviceM",
		//"H6210(SLCM)":  "ScLocalCtrlM",
	}
	GateNameTypeMap = map[string]string{
		"a1s2d3": "X1",
		"b1n2m3": "DTU",
		"q1w2e3": "路由器",
		//"H6210":    "x1y2z3",
	}
	DataTypeMap = map[string]string{
		"BIT":    "BIT",
		"BITX":   "BITX",
		"INT8":   "INT8",
		"UINT8":  "UINT8",
		"INT16":  "INT16",
		"UINT16": "UINT16",
		"INT32":  "INT32",
		"UINT32": "UINT32",
		"FLOAT":  "FLOAT",
		"STRING": "STRING",
	}
	ModeEnum = map[string]string{
		"SERVER":       "平台",
		"CLIENT":       "设备",
		"CLIENT_PARAM": "参数",
	}
	AccessEnum = map[string]string{
		"读写": "0",
		"只读": "1",
	}
	FuncTypeEnum = map[string]int{
		"线圈状态":   1,
		"离散输入状态": 2,
		"保持寄存器":  3,
		"输入寄存器":  4,
	}
	ControlCodeEnum = map[string]int{
		"强置单线圈":  5,
		"强置多线圈":  15,
		"预置单寄存器": 6,
		"预置多寄存器": 16,
	}
	SiemensAreaEnum = map[string]string{
		"V":  "数据存储区V",
		"I":  "输入继电器I",
		"Q":  "输出继电器Q",
		"M":  "辅助继电器M",
		"T":  "定时器T",
		"C":  "计数器C",
		"AI": "模拟输入映像寄存器AI",
		"AQ": "模拟输出映像寄存器AQ",
		"S":  "顺序控制继电器S",
	}
	MitsubshiAreaEnum = map[string]string{
		"Y":  "输出继电器Y",
		"M":  "辅助继电器M",
		"X":  "输入继电器X",
		"S":  "状态S",
		"D":  "数据寄存器D",
		"TS": "定时器触点TS",
		"TN": "定时器当前值TN",
		"CS": "计数器触点CS",
		"CN": "计数器当前值CN",
		"CW": "计数器(16位)CW",
		"CD": "计数器(32位)CD",
	}
	OmronAreaEnum = map[string]string{
		"CIO": "I/O存储区CIO",
		"W":   "工作区W",
		"H":   "保持区H",
		"A":   "辅助区A",
		"T":   "定时器区T",
		"C":   "计数器区C",
		"L":   "链接继电器区L",
		"D":   "数据存储区D",
	}
	MitsubshiOffsetEnum = map[string]int{
		"当前地址低8位": 0,
		"当前地址高8位": 1,
	}
)

// GateTypeMap
func GetGateTypeVal(gateType string) string {
	for k, v := range GateTypeMap {
		if k == gateType {
			return v
		}
	}
	return "b1n2m3"
}

// ModeEnum
func GetModeEnumName(modeKey string) string {
	if _, ok := ModeEnum[modeKey]; !ok {
		return "设备"
	}
	return ModeEnum[modeKey]
}

func GetModeEnumKey(modeName string) string {
	for k, v := range ModeEnum {
		if v == modeName {
			return k
		}
	}
	return "CLIENT"
}

// AccessEnum
func GetAccessByType(typeStr string) string {
	if _, ok := AccessEnum[typeStr]; !ok {
		return "0"
	}
	return AccessEnum[typeStr]
}

func GetAccessByVal(valStr string) string {
	for k, v := range AccessEnum {
		if v == valStr {
			return k
		}
	}
	return "读写"
}

// FuncTypeEnum
func GetFuncByName(name string) int {
	if _, ok := FuncTypeEnum[name]; !ok {
		return 3
	}
	return FuncTypeEnum[name]
}

func GetFuncByVal(val int) string {
	for k, v := range FuncTypeEnum {
		if v == val {
			return k
		}
	}
	return "保持寄存器"
}

// ControlCodeEnum
func GetControlByName(name string) int {
	if _, ok := ControlCodeEnum[name]; !ok {
		return 5
	}
	return ControlCodeEnum[name]
}

func GetControlByVal(val int) string {
	for k, v := range ControlCodeEnum {
		if v == val {
			return k
		}
	}
	return "强置单线圈"
}

// SiemensAreaEnum
func GetSiemensAreaByVal(val string) string {
	if _, ok := SiemensAreaEnum[val]; !ok {
		return "数据存储区V"
	}
	return SiemensAreaEnum[val]
}

func GetSiemensAreaByName(name string) string {
	for k, v := range SiemensAreaEnum {
		if v == name {
			return k
		}
	}
	return "V"
}

// MitsubshiAreaEnum
func GetMitsubshiAreaByVal(val string) string {
	if _, ok := MitsubshiAreaEnum[val]; !ok {
		return "输出继电器Y"
	}
	return MitsubshiAreaEnum[val]
}

func GetMitsubshiAreaByName(name string) string {
	for k, v := range MitsubshiAreaEnum {
		if v == name {
			return k
		}
	}
	return "Y"
}

// OmronAreaEnum
func GetOmronAreaByVal(val string) string {
	if _, ok := OmronAreaEnum[val]; !ok {
		return "I/O存储区CIO"
	}
	return OmronAreaEnum[val]
}

func GetOmronAreaByName(name string) string {
	for k, v := range OmronAreaEnum {
		if v == name {
			return k
		}
	}
	return "CIO"
}

// MitsubshiOffsetEnum
func GetMitsubshiOffsetByType(typeStr string) int {
	if _, ok := MitsubshiOffsetEnum[typeStr]; !ok {
		return 0
	}
	return MitsubshiOffsetEnum[typeStr]
}
